package com.zdxf.service.impl;

import com.zdxf.conf.CustomErrorHandler;
import com.zdxf.domain.IpDO;
import com.zdxf.domain.SystemInfoDO;
import com.zdxf.mapper.HostListMapper;
import com.zdxf.service.MonitorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import oshi.util.FormatUtil;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class MonitorServiceImpl implements MonitorService {
    private static IpDO[] ipList;
    @Autowired
    HostListMapper hostListMapper;
    @Autowired
    private RestTemplate restTemplate;

    @Override
    public List getCpuInfoList(Map params) {
        String path = "/client/getCpuInfo";
        return generateList(path, params);
    }

    @Override
    public List getMemInfoList(Map params) {
        String path = "/client/getMemInfo";
        return generateList(path, params);
    }

    @Override
    public List getDiskInfoList(Map params) {
        String path = "/client/getDiskInfo";
        return generateList(path, params);
    }

    @Override
    public List getDNetInfoList(Map params) {
        String path = "/client/getNetInfo";
        return generateList(path, params);
    }

    @Override
    public List getSysInfoList(Map params) {
        String path = "/client/getSysInfo";
        return generateList(path, params);
    }

    @Override
    public SystemInfoDO getCpuInfoSum() {
        String path = "/client/getCpuInfo";
        List resList = generateList(path, null);
        SystemInfoDO result = new SystemInfoDO();
        for (int i = 0; i < resList.size(); i++) {
            SystemInfoDO res = getServiceInfo(ipList[i].getUrl() + path);
            result.setCpuCount(res.getCpuCount() + result.getCpuCount());
            result.setSystemCpuLoad(res.getSystemCpuLoad() + result.getSystemCpuLoad());
            result.setUserCpuLoad(res.getUserCpuLoad() + result.getUserCpuLoad());
            result.setIowaitCpuLoad(res.getIowaitCpuLoad() + result.getIowaitCpuLoad());
            result.setIdleCpuLoad(res.getIdleCpuLoad() + result.getIdleCpuLoad());
            result.setSystemCpuLoadStr(new DecimalFormat("#.##%").format(result.getSystemCpuLoad()));
            result.setUserCpuLoadStr(new DecimalFormat("#.##%").format(result.getUserCpuLoad()));
            result.setIowaitCpuLoadStr(new DecimalFormat("#.##%").format(result.getIowaitCpuLoad()));
            result.setIdleCpuLoadStr(new DecimalFormat("#.##%").format(result.getIdleCpuLoad()));
        }
        return result;
    }

    @Override
    public SystemInfoDO getMemInfoSum() {
        String path = "/client/getMemInfo";
        List resList = generateList(path, null);
        SystemInfoDO result = new SystemInfoDO();
        for (int i = 0; i < resList.size(); i++) {
            SystemInfoDO res = getServiceInfo(ipList[i].getUrl() + path);
            result.setMemoryFree(res.getMemoryFree() + result.getMemoryFree());
            result.setMemoryTotal(res.getMemoryTotal() + result.getMemoryTotal());
            result.setMemoryUse(res.getMemoryUse() + result.getMemoryUse());
            result.setMemoryFreeStr(FormatUtil.formatBytes(result.getMemoryFree()));
            result.setMemoryTotalStr(FormatUtil.formatBytes(result.getMemoryTotal()));
            result.setMemoryUseStr(FormatUtil.formatBytes(result.getMemoryUse()));
        }
        return result;
    }

    @Override
    public SystemInfoDO getNetInfoSum() {
        String path = "/client/getNetInfo";
        List resList = generateList(path, null);
        SystemInfoDO result = new SystemInfoDO();
        for (int i = 0; i < resList.size(); i++) {
            SystemInfoDO res = getServiceInfo(ipList[i].getUrl() + path);
            result.setNetRecv(res.getNetRecv() + result.getNetRecv());
            result.setNetSent(res.getNetSent() + result.getNetSent());
            result.setNetRecvStr(FormatUtil.formatBytes(result.getNetRecv()));
            result.setNetSentStr(FormatUtil.formatBytes(result.getNetSent()));
        }
        return result;
    }

    @Override
    public SystemInfoDO getDiskInfoSum() {
        String path = "/client/getDiskInfo";
        List resList = generateList(path, null);
        SystemInfoDO result = new SystemInfoDO();
        for (int i = 0; i < resList.size(); i++) {
            SystemInfoDO res = getServiceInfo(ipList[i].getUrl() + path);
            result.setDisksFree(res.getDisksFree() + result.getDisksFree());
            result.setDisksUse(res.getDisksUse() + result.getDisksUse());
            result.setDisksTotal(res.getDisksTotal() + result.getDisksTotal());
            result.setDisksFreeStr(FormatUtil.formatBytes(result.getDisksFree()));
            result.setDisksUseStr(FormatUtil.formatBytes(result.getDisksUse()));
            result.setDisksTotalStr(FormatUtil.formatBytes(result.getDisksTotal()));
        }
        return result;
    }

    @Override
    public SystemInfoDO getCpuLoadSum() {
        String path = "/client/CpuLoadInfo";
        List resList = generateList(path, null);
        SystemInfoDO result = new SystemInfoDO();
        for (int i = 0; i < resList.size(); i++) {
            SystemInfoDO res = getServiceInfo(ipList[i].getUrl() + path);
            result.setCpuLoad1((double) Math.round((res.getCpuLoad1() + result.getCpuLoad1()) * 100) / 100);
            result.setCpuLoad5((double) Math.round((res.getCpuLoad5() + result.getCpuLoad5()) * 100) / 100);
            result.setCpuLoad15((double) Math.round((res.getCpuLoad15() + result.getCpuLoad15()) * 100) / 100);
        }
        return result;
    }

    @Override
    public List getAllInfo() {
        String path = "/client/getAllInfo";
        return generateList(path, null);
    }

    public List generateList(String path, Map params) {
        List<SystemInfoDO> list = new ArrayList<SystemInfoDO>();
        list.clear();
        ipList = hostListMapper.getHostList();
        System.out.println(ipList);
        for (int i = 0; i < ipList.length; i++) {
            if (params != null && params.get("id") != null && params.get("id").equals(ipList[i].getId() + "")) {
                SystemInfoDO res = getServiceInfo(ipList[i].getUrl() + path);
                res.setId(ipList[i].getId());
                res.setIp(ipList[i].getIp());
                res.setName(ipList[i].getName());
                list.add(res);
                break;
            }
            if (params == null || params.get("id") == null) {
                SystemInfoDO res = getServiceInfo(ipList[i].getUrl() + path);
                res.setId(ipList[i].getId());
                res.setIp(ipList[i].getIp());
                res.setName(ipList[i].getName());
                list.add(res);
            }

        }
        return list;
    }

    public SystemInfoDO getServiceInfo(String ip) {

        ResponseEntity<SystemInfoDO> exchange;

        try {
            exchange = restTemplate.exchange(ip, HttpMethod.GET, null, new ParameterizedTypeReference<SystemInfoDO>() {
            });
        } catch (Exception e) {
            return new SystemInfoDO(1);
        }


        SystemInfoDO body = exchange.getBody();
        System.out.println(body);
        return body;
    }
}
